package com.panfeng.xcloud.boss.provider.assets.web.rpc;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.panfeng.xcloud.boss.provider.assets.service.exchange.IExchangeOperateService;
import com.panfeng.xcloud.boss.provider.dto.request.ExchangeOperateReqDTO;
import com.panfeng.xcloud.boss.provider.rpc.assets.ExchangeOperateServiceFeignApi;
import com.panfeng.xcloud.common.core.web.vo.OrderDetailResponseVO;
import com.panfeng.xcloud.common.core.web.vo.ResponseVO;
import com.panfeng.xcloud.common.core.web.vo.TradeResponseVO;
import com.panfeng.xcloud.common.security.annotation.NotNeedAccess;
import com.panfeng.xcloud.common.security.annotation.NotNeedFeignAccess;
import com.panfeng.xcloud.common.security.web.support.BaseController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;

@Slf4j
@RestController
@Api(value = "API - ExchangeOperateServiceApiFeignClient", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public class ExchangeOperateServiceApiFeignClient extends BaseController implements ExchangeOperateServiceFeignApi {

    @Autowired
    private IExchangeOperateService iExchangeOperateService;

    @NotNeedAccess
    @NotNeedFeignAccess
    @PostMapping(value = "/feignApi/assets/getTotalAvaliableMoney", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiOperation(httpMethod = "POST", value = "rest-rpc初始化-getTotalAvaliableMoney查询账户总可用余额")
    @Override
    public ResponseVO getTotalAvaliableMoney(@RequestBody ExchangeOperateReqDTO exchangeOperateReqDTO) {
        try {
            log.info(">>> getTotalAvaliableMoney:{} <<<<", (null != exchangeOperateReqDTO ? JSON.toJSONString(exchangeOperateReqDTO) : ""));
            BigDecimal totalAvaliableMoney = iExchangeOperateService.getTotalAvaliableMoney(exchangeOperateReqDTO.getOperateBotReqDTO().getExchangeType(),
                    exchangeOperateReqDTO.getOperateBotReqDTO().getUserId(), exchangeOperateReqDTO.getValuationAsset());
            return ResponseVO.with(String.valueOf(totalAvaliableMoney));
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResponseVO.with(ResponseVO.FAIL, ResponseVO.FAIL, e);
        }
    }

    @NotNeedAccess
    @NotNeedFeignAccess
    @PostMapping(value = "/feignApi/assets/getRiskRate", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiOperation(httpMethod = "POST", value = "rest-rpc初始化-getRiskRate查询交易对保证金率")
    @Override
    public ResponseVO getRiskRate(@RequestBody ExchangeOperateReqDTO exchangeOperateReqDTO) {
        try {
            log.info(">>> getRiskRate:{} <<<<", (null != exchangeOperateReqDTO ? JSON.toJSONString(exchangeOperateReqDTO) : ""));
            BigDecimal riskRate = iExchangeOperateService.getRiskRate(exchangeOperateReqDTO.getOperateBotReqDTO().getExchangeType(),
                    exchangeOperateReqDTO.getOperateBotReqDTO().getUserId(), exchangeOperateReqDTO.getContractCode(), exchangeOperateReqDTO.getOperateBotReqDTO().getDirection());
            return ResponseVO.with(String.valueOf(riskRate));
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResponseVO.with(ResponseVO.FAIL, ResponseVO.FAIL, e);
        }
    }

    @NotNeedAccess
    @NotNeedFeignAccess
    @PostMapping(value = "/feignApi/assets/getAvaliablePosition", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiOperation(httpMethod = "POST", value = "rest-rpc初始化-getAvaliablePosition查询某交易对的可用仓位")
    @Override
    public ResponseVO getAvaliablePosition(@RequestBody ExchangeOperateReqDTO exchangeOperateReqDTO) {
        try {
            log.info(">>> getAvaliablePosition:{} <<<<", (null != exchangeOperateReqDTO ? JSON.toJSONString(exchangeOperateReqDTO) : ""));
            BigDecimal avaliablePosition = iExchangeOperateService.getAvaliablePosition(exchangeOperateReqDTO.getOperateBotReqDTO().getExchangeType(),
                    exchangeOperateReqDTO.getOperateBotReqDTO().getUserId(), exchangeOperateReqDTO.getContractCode(), exchangeOperateReqDTO.getOperateBotReqDTO().getDirection(),
                    exchangeOperateReqDTO.getOperateBotReqDTO().getLeverRate());
            return ResponseVO.with(String.valueOf(avaliablePosition));
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResponseVO.with(ResponseVO.FAIL, ResponseVO.FAIL, e);
        }
    }

    @NotNeedAccess
    @NotNeedFeignAccess
    @PostMapping(value = "/feignApi/assets/getPositionAgvPrice", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiOperation(httpMethod = "POST", value = "rest-rpc初始化-getPositionAgvPrice查询某交易对的开仓均价")
    @Override
    public ResponseVO getPositionAgvPrice(@RequestBody ExchangeOperateReqDTO exchangeOperateReqDTO) {
        try {
            log.info(">>> getPositionAgvPrice:{} <<<<", (null != exchangeOperateReqDTO ? JSON.toJSONString(exchangeOperateReqDTO) : ""));
            BigDecimal avaliablePosition = iExchangeOperateService.getPositionAgvPrice(exchangeOperateReqDTO.getOperateBotReqDTO().getExchangeType(),
                    exchangeOperateReqDTO.getOperateBotReqDTO().getUserId(), exchangeOperateReqDTO.getContractCode(), exchangeOperateReqDTO.getOperateBotReqDTO().getDirection(),
                    exchangeOperateReqDTO.getOperateBotReqDTO().getLeverRate());
            return ResponseVO.with(String.valueOf(avaliablePosition));
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResponseVO.with(ResponseVO.FAIL, ResponseVO.FAIL, e);
        }
    }

    @NotNeedAccess
    @NotNeedFeignAccess
    @PostMapping(value = "/feignApi/assets/getAvaliableMoney", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiOperation(httpMethod = "POST", value = "rest-rpc初始化-getAvaliableMoney查询某交易对的可用余额")
    @Override
    public ResponseVO getAvaliableMoney(@RequestBody ExchangeOperateReqDTO exchangeOperateReqDTO) {
        try {
            log.info(">>> getAvaliableMoney:{} <<<<", (null != exchangeOperateReqDTO ? JSON.toJSONString(exchangeOperateReqDTO) : ""));
            BigDecimal avaliableMoney = iExchangeOperateService.getAvaliableMoney(exchangeOperateReqDTO.getOperateBotReqDTO().getExchangeType(),
                    exchangeOperateReqDTO.getOperateBotReqDTO().getUserId(), exchangeOperateReqDTO.getContractCode());
            return ResponseVO.with(String.valueOf(avaliableMoney));
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResponseVO.with(ResponseVO.FAIL, ResponseVO.FAIL, e);
        }
    }

    @NotNeedAccess
    @NotNeedFeignAccess
    @PostMapping(value = "/feignApi/assets/getAvaliablePieces", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiOperation(httpMethod = "POST", value = "rest-rpc初始化-getAvaliablePieces查询某交易对的可开张数")
    @Override
    public ResponseVO getAvaliablePieces(@RequestBody ExchangeOperateReqDTO exchangeOperateReqDTO) {
        try {
            log.info(">>> getAvaliablePieces:{} <<<<", (null != exchangeOperateReqDTO ? JSON.toJSONString(exchangeOperateReqDTO) : ""));
            BigDecimal avaliablePieces = iExchangeOperateService.getAvaliablePieces(exchangeOperateReqDTO.getOperateBotReqDTO().getExchangeType(),
                    exchangeOperateReqDTO.getOperateBotReqDTO().getUserId(), exchangeOperateReqDTO.getOperateBotReqDTO().getDestinationCoin(),
                    exchangeOperateReqDTO.getOperateBotReqDTO().getSourceCoin(), exchangeOperateReqDTO.getOperateBotReqDTO().getDirection(),
                    exchangeOperateReqDTO.getOperateBotReqDTO().getLeverRate());
            return ResponseVO.with(String.valueOf(avaliablePieces));
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResponseVO.with(ResponseVO.FAIL, ResponseVO.FAIL, e);
        }
    }

    @NotNeedAccess
    @NotNeedFeignAccess
    @PostMapping(value = "/feignApi/assets/trade", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiOperation(httpMethod = "POST", value = "rest-rpc初始化-trade交易所下市价单")
    @Override
    public ResponseVO trade(@RequestBody ExchangeOperateReqDTO exchangeOperateReqDTO) {
        try {
            log.info(">>> trade:{} <<<<", (null != exchangeOperateReqDTO ? JSON.toJSONString(exchangeOperateReqDTO) : ""));
            TradeResponseVO trade = iExchangeOperateService.trade(exchangeOperateReqDTO.getOperateBotReqDTO().getExchangeType(), exchangeOperateReqDTO.getOperateBotReqDTO());
            return ResponseVO.with(trade);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResponseVO.with(ResponseVO.FAIL, ResponseVO.FAIL, e);
        }
    }

    @NotNeedAccess
    @NotNeedFeignAccess
    @PostMapping(value = "/feignApi/assets/getOrderDetail", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiOperation(httpMethod = "POST", value = "rest-rpc初始化-getOrderDetail获取订单详情")
    @Override
    public ResponseVO getOrderDetail(@RequestBody ExchangeOperateReqDTO exchangeOperateReqDTO) {
        try {
            log.info(">>> getOrderDetail:{} <<<<", (null != exchangeOperateReqDTO ? JSON.toJSONString(exchangeOperateReqDTO) : ""));
            OrderDetailResponseVO orderDetail = iExchangeOperateService.getOrderDetail(exchangeOperateReqDTO.getOperateBotReqDTO().getExchangeType(),
                    exchangeOperateReqDTO.getOperateBotReqDTO(), exchangeOperateReqDTO.getTradeResponseVO());
            return ResponseVO.with(orderDetail);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResponseVO.with(ResponseVO.FAIL, ResponseVO.FAIL, e);
        }
    }

    @NotNeedAccess
    @NotNeedFeignAccess
    @PostMapping(value = "/feignApi/assets/transferInner", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiOperation(httpMethod = "POST", value = "rest-rpc初始化-transferInner同账户内资金划转")
    @Override
    public ResponseVO transferInner(@RequestBody ExchangeOperateReqDTO exchangeOperateReqDTO) {
        try {
            log.info(">>> transferInner:{} <<<<", (null != exchangeOperateReqDTO ? JSON.toJSONString(exchangeOperateReqDTO) : ""));
            String orderId = iExchangeOperateService.transferInner(exchangeOperateReqDTO.getInnerTransferVO().getExchangeType(),
                    exchangeOperateReqDTO.getInnerTransferVO());
            return ResponseVO.with(orderId);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResponseVO.with(ResponseVO.FAIL, ResponseVO.FAIL, e);
        }
    }

    @NotNeedAccess
    @NotNeedFeignAccess
    @PostMapping(value = "/feignApi/assets/getAppearMarketPrice", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiOperation(httpMethod = "POST", value = "rest-rpc初始化-getAppearMarketPrice获取展示市价")
    @Override
    public ResponseVO getAppearMarketPrice(@RequestBody ExchangeOperateReqDTO exchangeOperateReqDTO) {
        try {
            log.info(">>> getAppearMarketPrice:{} <<<<", (null != exchangeOperateReqDTO ? JSON.toJSONString(exchangeOperateReqDTO) : ""));
            BigDecimal appearMarketPrice = iExchangeOperateService.getAppearMarketPrice(exchangeOperateReqDTO.getOperateBotReqDTO().getExchangeType(),
                    exchangeOperateReqDTO.getOperateBotReqDTO().getUserId(), exchangeOperateReqDTO.getOperateBotReqDTO().getDestinationCoin(),
                    exchangeOperateReqDTO.getOperateBotReqDTO().getSourceCoin());
            return ResponseVO.with(String.valueOf(appearMarketPrice));
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResponseVO.with(ResponseVO.FAIL, ResponseVO.FAIL, e);
        }
    }

    @NotNeedAccess
    @NotNeedFeignAccess
    @PostMapping(value = "/feignApi/assets/getMarketPriceDepth", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiOperation(httpMethod = "POST", value = "rest-rpc初始化-getMarketPriceDepth获取行情深度,供计算使用")
    @Override
    public ResponseVO getMarketPriceDepth(@RequestBody ExchangeOperateReqDTO exchangeOperateReqDTO) {
        try {
            log.info(">>> getMarketPriceDepth:{} <<<<", (null != exchangeOperateReqDTO ? JSON.toJSONString(exchangeOperateReqDTO) : ""));
            JSONObject marketPriceDepth = iExchangeOperateService.getMarketPriceDepth(exchangeOperateReqDTO.getOperateBotReqDTO().getExchangeType(),
                    exchangeOperateReqDTO.getOperateBotReqDTO().getUserId(), exchangeOperateReqDTO.getOperateBotReqDTO().getDestinationCoin(),
                    exchangeOperateReqDTO.getOperateBotReqDTO().getSourceCoin());
            return ResponseVO.with(marketPriceDepth);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResponseVO.with(ResponseVO.FAIL, ResponseVO.FAIL, e);
        }
    }

    @NotNeedAccess
    @NotNeedFeignAccess
    @PostMapping(value = "/feignApi/assets/getCandleStick", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiOperation(httpMethod = "POST", value = "rest-rpc初始化-getCandleStick获取K线数据")
    @Override
    public ResponseVO getCandleStick(@RequestBody ExchangeOperateReqDTO exchangeOperateReqDTO) {
        try {
            log.info(">>> getCandleStick:{} <<<<", (null != exchangeOperateReqDTO ? JSON.toJSONString(exchangeOperateReqDTO) : ""));
            JSONObject candleStick = iExchangeOperateService.getCandleStick(exchangeOperateReqDTO.getOperateBotReqDTO().getExchangeType(),
                    exchangeOperateReqDTO.getOperateBotReqDTO().getUserId(), exchangeOperateReqDTO.getOperateBotReqDTO().getDestinationCoin(),
                    exchangeOperateReqDTO.getOperateBotReqDTO().getSourceCoin(),exchangeOperateReqDTO.getCandleStickVO().getInterval(), exchangeOperateReqDTO.getCandleStickVO().getStartTime(),
                    exchangeOperateReqDTO.getCandleStickVO().getEndTime(), exchangeOperateReqDTO.getCandleStickVO().getLimit());
            return ResponseVO.with(candleStick);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResponseVO.with(ResponseVO.FAIL, ResponseVO.FAIL, e);
        }
    }

}
